#! /usr/bin/python
import os
import glob
import string
import random

perfCounters = []
bersBefore = []
bersAfter = []

def writePerCountersToFile(dir, prefix):
    with open(dir+'/'+prefix+'.ave.out', 'w') as f:
        print 'write prefix file' +  prefix
        for ber in bersBefore:
            f.write(str(ber)+' ')
        f.write('\n')
        for ber in bersAfter:
            f.write(str(ber)+' ')
        f.write('\n')
        for i in range(3, 19):
            f.write(str(perfCounters[i]) + '\n')
    f.closed

def averagingCounters(filenum):
    global perfCounters
    global bersBefore
    global bersAfter
    perfCounters = map(lambda x: x/filenum, perfCounters)
    bersBefore = map(lambda x: x/filenum, bersBefore)
    bersAfter = map(lambda x: x/filenum, bersAfter)

def computeAverageForCurrentDirectory(files):
    global perfCounters
    global bersBefore
    global bersAfter
    perfCounters = [0] * 19
    bersBefore = []
    bersAfter = []
    for fl in files:
        fh = open(fl)
        lines = fh.readlines()
        for i in range(3, 19):
            perfCounters[i] += float(lines[i])
        bers = string.split(lines[2])
        if (len(bersBefore) == 0):
            bersBefore = [0] * (len(bers)/2)
            bersAfter = [0] * (len(bers)/2)
        bersBefore = [sum(pair) for pair in zip(bersBefore, map(lambda i: float(bers[i]),filter(lambda i: i%2 == 0,range(len(bers)))))]
        bersAfter = [sum(pair) for pair in zip(bersAfter, map(lambda i: float(bers[i]),filter(lambda i: i%2 == 1,range(len(bers)))))]
        fh.closed
    averagingCounters(float(len(files)))

def generateDataFileForGnuPlot(dir, prefix, t):
    length = len(bersBefore)
    period = t * 3600
    if prefix == 'S':
        period /= 4
    with open(dir+'/'+prefix+'.ber.dat', 'w') as f:
        f.write('#Time' + '  ' + 'BERBefore' + '  ' + 'BERAfter' + '\n')
        for i in range(0, length):
            f.write(str((i+1)*period) + '  ' + str(bersBefore[i]) + '  ' + str(bersAfter[i]) + '\n')
    f.closed




def plotBER(dir):
    from subprocess import call
    call(['./plot-bers-before-ecc.gnu', dir])


def computeAverageForEachDirectory():
    dirs = sorted([f for f in os.listdir(os.getcwd()) if os.path.isdir(os.path.join(os.getcwd(), f))], key=lambda x: int(x))
    for dir in dirs:
        t = int(dir)
        sfiles = glob.glob(dir + '/?S*')
        nfiles = glob.glob(dir + '/?N*')
        print "Directory: " + dir
        print "Multiphase data file#: " + str(len(sfiles))
        print "Naive scheme data file#: " + str(len(nfiles))
        if len(sfiles) > 0:
            if (t == 12):
                sfiles = random.sample(sfiles, 800)
            else:
                sfiles = random.sample(sfiles, 320)
            # process multiphase scrubbing data
            computeAverageForCurrentDirectory(sfiles)
            writePerCountersToFile(dir, 'S')
            generateDataFileForGnuPlot(dir, 'S', t)
        if len(nfiles) > 0:
            nfiles = random.sample(nfiles, 320)
            # process naive scrubbing data
            computeAverageForCurrentDirectory(nfiles)
            writePerCountersToFile(dir, 'N')
            generateDataFileForGnuPlot(dir, 'N', t)
        if (len(sfiles) > 0) and (len(nfiles) > 0):
            # plot N.ber.dat and S.ber.dat into one figure
            plotBER(dir)


def plotFinalBER():
    from subprocess import call
    call(['./plot-final-ber.gnu', 'final-ber'])

def generateAverageFinalBerData(sfile, nfile, f, t):
    fh1 = open(sfile)
    fh2 = open(nfile)
    slines = fh1.readlines()
    nlines = fh2.readlines()
    f.write(str(t) + '  ' + str(float(nlines[8])) + '  ' + str(float(slines[8])) + '\n')
    fh1.closed
    fh2.closed

def collectFinalBers():
    dirs = sorted([f for f in os.listdir(os.getcwd()) if os.path.isdir(os.path.join(os.getcwd(), f))], key=lambda x: int(x))
    with open('final-ber.dat', 'w') as f:
        f.write('Period' + '  ' + 'Naive' + '  ' + 'Multi-phase' + '\n')
        for dir in dirs:
            t = int(dir)
            sfiles = glob.glob(dir + '/S.ave.out')
            nfiles = glob.glob(dir + '/N.ave.out')
            print "Directory: " + dir
            print "Multiphase average data file#: " + str(len(sfiles))
            print "Naive scheme average data file#: " + str(len(nfiles))
            if (len(sfiles) == 1) and (len(nfiles) == 1):
                generateAverageFinalBerData(sfiles[0], nfiles[0], f, t)
    f.closed
    print "Finish writing average final bers"
    plotFinalBER()

def plotIterNums():
    from subprocess import call
    call(['./plot-iternum.gnu', 'ave-ldpc-iternum'])

def generateAverageIterNumData(sfile, nfile, f, t):
    fh1 = open(sfile)
    fh2 = open(nfile)
    slines = fh1.readlines()
    nlines = fh2.readlines()
    f.write(str(t) + '  ' + str(float(nlines[2])) + '  ' + str(float(slines[2])) + '\n')
    fh1.closed
    fh2.closed

def collectIterNums():
    dirs = sorted([f for f in os.listdir(os.getcwd()) if os.path.isdir(os.path.join(os.getcwd(), f))], key=lambda x: int(x))
    with open('ave-ldpc-iternum.dat', 'w') as f:
        f.write('Period' + '  ' + 'Naive' + '  ' + 'Multi-phase' + '\n')
        for dir in dirs:
            t = int(dir)
            sfiles = glob.glob(dir + '/S.ave.out')
            nfiles = glob.glob(dir + '/N.ave.out')
            print "Directory: " + dir
            print "Multiphase average data file#: " + str(len(sfiles))
            print "Naive scheme average data file#: " + str(len(nfiles))
            if (len(sfiles) == 1) and (len(nfiles) == 1):
                generateAverageIterNumData(sfiles[0], nfiles[0], f, t)
    f.closed
    print "Finish writing average iteration numbers"
    plotIterNums()

def plotSuccessRate():
    from subprocess import call
    call(['./plot-success-rate.gnu', 'block-error-rate'])

def generateAverageDecodeSuccessRate(sfile, nfile, f, t):
    fh1 = open(sfile)
    fh2 = open(nfile)
    slines = fh1.readlines()
    nlines = fh2.readlines()
    nsrate = 1 - float(nlines[4])/(float(nlines[4]) + float(nlines[5]))
    ssrate = 1 - float(slines[4])/(float(slines[4]) + float(slines[5]))
    f.write(str(t) + '  ' + str(nsrate) + '  ' + str(ssrate) + '\n')
    fh1.closed
    fh2.closed

def collectDecodeSuccessRate():
    dirs = sorted([f for f in os.listdir(os.getcwd()) if os.path.isdir(os.path.join(os.getcwd(), f))], key=lambda x: int(x))
    with open('block-error-rate.dat', 'w') as f:
        f.write('Period' + '  ' + 'Naive' + '  ' + 'Multi-phase' + '\n')
        for dir in dirs:
            t = int(dir)
            sfiles = glob.glob(dir + '/S.ave.out')
            nfiles = glob.glob(dir + '/N.ave.out')
            print "Directory: " + dir
            print "Multiphase average data file#: " + str(len(sfiles))
            print "Naive scheme average data file#: " + str(len(nfiles))
            if (len(sfiles) == 1) and (len(nfiles) == 1):
                generateAverageDecodeSuccessRate(sfiles[0], nfiles[0], f, t)
    f.closed
    print "Finish writing average decoding successful rate"
    plotSuccessRate()

computeAverageForEachDirectory()
collectFinalBers()
collectIterNums()
collectDecodeSuccessRate()


# The mapping between performance counter elements and the actual counters:
#         average_iter_num += float(lines[2])
#         average_error_num += float(lines[3])
#         average_correct_blk_num += float(lines[4])
#         average_error_blk_num += float(lines[5])
#         average_undet_blk_num += float(lines[6])
#         average_det_blk_num += float(lines[7])
#         average_final_ber += float(lines[8])
#         average_mem_bit_num += float(lines[9])
#         average_cleanup_bit_num += float(lines[10])  
#         num_seg_scrubbed += float(lines[11])
#         average_ber_before_decode_meta += float(lines[12])
#         average_iter_num_meta += float(lines[13])
#         average_error_num_meta += float(lines[14])
#         average_correct_blk_num_meta += float(lines[15])
#         average_error_blk_num_meta += float(lines[16])
#         average_compressed_metadata_size += float(lines[17])


